package se.webbzon.oschi01.worldeditor;

import java.nio.ByteBuffer;

import se.webbzon.oschi01.friendly.Friendly;
import se.webbzon.oschi01.worldobject.WorldObject;

public abstract class WorldObjectDeflation {
	
	// The available properties for the world object deflaiton
	public static final int SKIP_CREATION	= (1<<0);
	
	// The properties for this deflation
	private final int properties;
	
	// An array containing all world object dependencies for this 
	// world object deflation
	private final WorldObject[] dependencies;
	
	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new world object deflation with a given set of
	 * properties and a given array of world object dependencies. **/
	public WorldObjectDeflation(int deflationProperties, 
								WorldObject[] dependencies) {
		this.dependencies = dependencies;
		properties = deflationProperties;
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns the properties that are set for this world object deflation. **/
	public int getProperties() {
		return properties;
	}
	
	/** Returns true if the deflation should be initialized but not
	 * created in the world area upon inflation. **/
	public boolean skipCreation() {
		return isSet(properties,SKIP_CREATION);
	}
	
	/** Returns the number of dependencies of this world object deflation. **/
	public int dependencies() {
		return trueDependencies();
	}
	
	/** Returns the (n+1):th dependency of this world object deflation. **/
	public WorldObject getDependency(int n) {
		return getTrueDependency(n);
	}
	
	/** Returns an array of all dependencies for this deflatable world object. **/
	public WorldObject[] getDependencies() {
		return getTrueDependencies();
	}
	
	/** Loads data from a byte buffer into the world object
	 * deflation. This method is invoked when a world object
	 * is deserialized from a world area blueprint. **/
	public abstract void inflate(ByteBuffer buffer);
	
	/** Returns the data stored in a world object deflation as
	 * a byte buffer wrapped around an serializable array. The
	 * parameter "allocate" is used to signal a super method
	 * to allocate a given amount of bytes for the returned
	 * byte buffer. **/
	public abstract ByteBuffer deflate(int allocate);
	
	/*============================================================
	Friendly Methods
	============================================================*/
	
	/** Returns the true number of dependencies of this world object 
	 * deflation. The method can not be override and will therefore
	 * return the number of dependencies even if the deflation is
	 * extended and the method dependencies() is override.  **/
	@Friendly final int trueDependencies() {
		if (dependencies == null)
			return 0;
		else
			return dependencies.length;
	}
	
	/** Returns the true (n+1):th dependency of this world object deflation. 
	 * This method can not be override. **/
	@Friendly final WorldObject getTrueDependency(int n) {
		return dependencies[n];
	}
	
	/** Returns the true array of all dependencies for this deflatable 
	 * world object. **/
	@Friendly final WorldObject[] getTrueDependencies() {
		return dependencies;
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Returns true if the given property is set in the given properties. **/
	private static final boolean isSet(int properties, int property) {
		return ((properties & property) == property);
	}

}
